package fun.tan90.easy.binlog.worker.job;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.github.benmanes.caffeine.cache.stats.CacheStats;
import fun.tan90.easy.binlog.base.constants.EasyBinlogConstants;
import fun.tan90.easy.binlog.worker.client.EbWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * description TODO
 * company 铁人科技
 *
 * @author 陈浩杰
 * @date 2023/9/7 20:32
 */
@Slf4j
@Component
public class CacheStatsJob {

    @Resource
    EbWorker ebWorker;

    @Resource
    Map<String, LoadingCache<?, ?>> loadingCacheMap;

    @Scheduled(cron = "0 0/1 * * * ?")
    public void cacheStatsTask() {
        if (!ebWorker.getConfig().getMetric()) {
            return;
        }
        List<String> fieldList = new ArrayList<>();
        List<String> tagList = new ArrayList<>();
        String workId = ebWorker.getWorkId();
        for (Map.Entry<String, LoadingCache<?, ?>> entry : loadingCacheMap.entrySet()) {
            String cacheName = entry.getKey();
            CacheStats stats = entry.getValue().stats();

            //总访问次数
            fieldList.add(StrUtil.format("{}={}", "request_count", stats.requestCount()));
            //命中次数
            fieldList.add(StrUtil.format("{}={}", "hit_count", stats.hitCount()));
            //未命中次数
            fieldList.add(StrUtil.format("{}={}", "miss_count", stats.missCount()));
            //命中率
            fieldList.add(StrUtil.format("{}={}", "hit_rate", stats.hitRate() * 100));
            //未命中率
            fieldList.add(StrUtil.format("{}={}", "miss_rate", stats.missRate() * 100));


            //加载次数
            fieldList.add(StrUtil.format("{}={}", "load_count", stats.loadCount()));
            //加载成功次数
            fieldList.add(StrUtil.format("{}={}", "load_success_count", stats.loadSuccessCount()));
            //加载失败次数
            fieldList.add(StrUtil.format("{}={}", "load_failure_count", stats.loadFailureCount()));

            //加载新值平时耗时(ns)
            fieldList.add(StrUtil.format("{}={}", "average_load_penalty", stats.averageLoadPenalty()));
            //总加载时间(ns)
            fieldList.add(StrUtil.format("{}={}", "total_load_time", stats.totalLoadTime()));

            String fieldSet = String.join(",", fieldList);
            fieldList.clear();

            tagList.add(StrUtil.format("{}={}", "work_id", workId));
            tagList.add(StrUtil.format("{}={}", "cache_name", cacheName));
            String tagSet = String.join(",", tagList);
            tagList.clear();

            String schemalessSql = StrUtil.format("{},{} {} {}", "caffeine_cache_stats", tagSet, fieldSet, DateUtil.beginOfDay(new Date()).getTime());
            ebWorker.send(EasyBinlogConstants.METRIC_COLLECT, schemalessSql);
        }
    }
}